#include "stdafx.h"
#include "com_fun.h"
#include <math.h>
// logic coordinate <-> fact coordinate
void	VPtoDP(int x, int y, DOUBLE &X, DOUBLE &Y,const SHAPEPOS *pshp) {
	ASSERT(pshp!=NULL);
		// x,y not in vRect;
		if(x<=pshp->vRect.left||x>=pshp->vRect.right||y<=pshp->vRect.top||y>=pshp->vRect.bottom)
			return;
	if(pshp ->MapMode == MM_GEOGAUSS)
	{
		int lx	= pshp->vRect.bottom - y;
		int ly	= x	- pshp->vRect.left;
		X = pshp ->dOPoint.x + lx * pshp ->ScaleX;
		Y = pshp ->dOPoint.y + ly * pshp ->ScaleY;
	}else if(pshp ->MapMode == MM_GEOWGS84)
	{
		int lx	= x	- pshp->vRect.left;
		int ly	= pshp->vRect.bottom - y;
		X = pshp ->dOPoint.x + lx * pshp ->ScaleX;
		Y = pshp ->dOPoint.y + ly * pshp ->ScaleY;
	}
}

void	DPtoVP(DOUBLE X, DOUBLE Y, long &x, long &y,const SHAPEPOS *pshp) {
	ASSERT(pshp!=NULL);
	if(pshp ->MapMode == MM_GEOGAUSS)
	{
		x = (int)((Y - pshp ->dOPoint.y)/pshp ->ScaleY + pshp->vRect.left + 0.5);
		y = pshp ->vRect.bottom - (int)((X - pshp ->dOPoint.x)/pshp ->ScaleX + 0.5);
	}else if(pshp ->MapMode == MM_GEOWGS84)
	{
		x = (int)((X - pshp->dOPoint.x)/pshp->ScaleX + pshp->vRect.left + 0.5);
		y = pshp ->vRect.bottom - (int)((Y - pshp ->dOPoint.y)/pshp ->ScaleY + 0.5);
	}
}

DOUBLE	VLtoDL(int l,const SHAPEPOS *pshp) {
	return l*pshp ->blc;
}

int DLtoVL(DOUBLE l,const SHAPEPOS *pshp) {
	return (int)(l/pshp ->blc);
}

// public math methods
double GetAngle(DOUBLE bx,DOUBLE by,DOUBLE x,DOUBLE y) {
	double ang;
	if(fabs(bx -x)<=0.001) {
		if(y>by)
			return _PI/2;
		else
			return _PI*3/2;
	}
	else {
		DOUBLE d = (DOUBLE)GetDistance(bx,by,x,y);
		DOUBLE kk = (x - bx)/d;
		ang = acos(kk);
		if(y<by)
			ang = _PI*2 -ang;
	}
	return ang;
}

double GetDistance(DOUBLE bx,DOUBLE by,DOUBLE x,DOUBLE y) {
	return sqrt((bx-x)*(bx-x)+(by-y)*(by-y));
}

BOOL RectCross(DOUBLE x1, DOUBLE y1, DOUBLE x2, DOUBLE y2,const SHAPEPOS shp) {
	if(x1>=shp.dRect.right||x2<=shp.dRect.left||
		y1>=shp.dRect.bottom||y2<=shp.dRect.top)
		return FALSE;
	else 
		return TRUE;
}

DOUBLE PointAtLine(DOUBLE x,DOUBLE y,DOUBLE x1,DOUBLE y1,DOUBLE x2,DOUBLE y2)	{
	double xx;
	double a=0.0f,b=0.0f,c=0.0f,s,S;
	a = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
	b = sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
	c = sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
	s = (a+b+c)/2;
	S = sqrt(s*(s-a)*(s-b)*(s-c));
	xx = (S*2)/a;
	return (DOUBLE)xx;
}
BOOL PointInCircle(DOUBLE x,DOUBLE y,DOUBLE x1,DOUBLE y1,DOUBLE radius) {
	ASSERT(radius>=0);
	double dd = sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
	return (dd <= radius);
}

BOOL	PointInRgn(DOUBLE x,DOUBLE y,DPOINT*PointList,int nCount) {
	BOOL btrue = FALSE;
	CRgn rgn;
	DOUBLE x1,y1;
	x1=x;	y1=y;
	if(nCount<3)return false;
	POINT *pPoint;
	pPoint=new POINT[nCount];
	for(int i=0;i<nCount;i++) {
		pPoint[i].x=(long)PointList[i].x;
		pPoint[i].y=(long)PointList[i].y;
	}
	btrue = rgn.CreatePolygonRgn(pPoint,nCount,0);
	if(!btrue)	return btrue;
	btrue = rgn.PtInRegion((int)x1,(int)y1);
	rgn.DeleteObject();
	return btrue;
}

BOOL	PointInRgn(DOUBLE x,DOUBLE y,const DOUBLERECT rc){
	DOUBLERECT rctemp;
	rctemp.left = rc.left;
	rctemp.top  = rc.top;
	rctemp.right= rc.right;
	rctemp.bottom=rc.bottom;
	if(x<rctemp.left||x>rctemp.right||y<rctemp.top||y> rctemp.bottom)
		return FALSE;
	return TRUE;
}

void	ScalePoint(DOUBLE bx, DOUBLE by, DOUBLE xScal, DOUBLE yScal,DOUBLE &x,DOUBLE &y)	{
	x = bx + (x - bx)*xScal;
	y = by + (y - by)*yScal;
}

void	RotatePoint(DOUBLE bx,DOUBLE by,double ang,DOUBLE &x,DOUBLE&y) {
	double ang1 = GetAngle(bx,by,x,y);
	double d = GetDistance(bx,by,x,y);
	x = bx + (DOUBLE)(d*cos(ang+ang1));
	y = by + (DOUBLE)(d*sin(ang+ang1));
}